/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package compilador.view;



import compilador.Compilador;
import compilador.pojo.Mensagem;
import compilador.pojo.MensagemErro;
import compilador.util.ManipuladorDeArquivo;
import java.awt.Color;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.text.BadLocationException;



/**
 *
 * @author H
 */
public class CompiladorView extends javax.swing.JFrame {


    private File arquivo = null;



    /**
     * Creates new form CompiladorView
     */
    public CompiladorView() {
        initComponents();
        //this.btnCompilar.setEnabled(false);
    }



    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        pnlEditor = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtEditor = new javax.swing.JTextArea();
        lblLinha = new javax.swing.JLabel();
        txtLinha = new javax.swing.JTextField();
        lblColuna = new javax.swing.JLabel();
        txtColuna = new javax.swing.JTextField();
        btnCompilar = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        txtCaminho = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        txtErro = new javax.swing.JTextArea();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jmenuAbrir = new javax.swing.JMenuItem();
        jmenuSalvar = new javax.swing.JMenuItem();
        jmenuFechar = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        jmenuSair = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Compilador");

        pnlEditor.setBorder(javax.swing.BorderFactory.createTitledBorder("Editor"));

        txtEditor.setColumns(20);
        txtEditor.setRows(5);
        txtEditor.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                txtEditorMouseClicked(evt);
            }
        });
        txtEditor.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtEditorFocusGained(evt);
            }
        });
        txtEditor.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtEditorKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtEditorKeyReleased(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                txtEditorKeyTyped(evt);
            }
        });
        jScrollPane1.setViewportView(txtEditor);

        lblLinha.setText("Linha:");

        txtLinha.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        txtLinha.setEnabled(false);

        lblColuna.setText("Coluna:");

        txtColuna.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        txtColuna.setEnabled(false);

        btnCompilar.setText("Compilar");
        btnCompilar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCompilarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlEditorLayout = new javax.swing.GroupLayout(pnlEditor);
        pnlEditor.setLayout(pnlEditorLayout);
        pnlEditorLayout.setHorizontalGroup(
            pnlEditorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlEditorLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlEditorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1)
                    .addGroup(pnlEditorLayout.createSequentialGroup()
                        .addGap(0, 517, Short.MAX_VALUE)
                        .addComponent(btnCompilar, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(319, 319, 319)
                        .addComponent(lblLinha)
                        .addGap(18, 18, 18)
                        .addComponent(txtLinha, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(lblColuna)
                        .addGap(18, 18, 18)
                        .addComponent(txtColuna, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        pnlEditorLayout.setVerticalGroup(
            pnlEditorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlEditorLayout.createSequentialGroup()
                .addGap(8, 8, 8)
                .addGroup(pnlEditorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblLinha)
                    .addComponent(txtLinha, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblColuna)
                    .addComponent(txtColuna, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnCompilar))
                .addGap(18, 18, 18)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 406, Short.MAX_VALUE)
                .addContainerGap())
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Caminho"));

        txtCaminho.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        txtCaminho.setEnabled(false);
        txtCaminho.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtCaminhoActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(txtCaminho, javax.swing.GroupLayout.DEFAULT_SIZE, 605, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(txtCaminho, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Erro"));

        txtErro.setColumns(20);
        txtErro.setRows(5);
        jScrollPane2.setViewportView(txtErro);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 617, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jMenu1.setText("Arquivo");
        jMenu1.setToolTipText("");
        jMenu1.setBorderPainted(true);

        jmenuAbrir.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        jmenuAbrir.setText("Abrir");
        jmenuAbrir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jmenuAbrirActionPerformed(evt);
            }
        });
        jMenu1.add(jmenuAbrir);

        jmenuSalvar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        jmenuSalvar.setText("Salvar");
        jmenuSalvar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jmenuSalvarActionPerformed(evt);
            }
        });
        jMenu1.add(jmenuSalvar);

        jmenuFechar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
        jmenuFechar.setText("Fechar");
        jmenuFechar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jmenuFecharActionPerformed(evt);
            }
        });
        jMenu1.add(jmenuFechar);
        jMenu1.add(jSeparator1);

        jmenuSair.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.CTRL_MASK));
        jmenuSair.setText("Sair");
        jmenuSair.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jmenuSairActionPerformed(evt);
            }
        });
        jMenu1.add(jmenuSair);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlEditor, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(pnlEditor, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jmenuAbrirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuAbrirActionPerformed
        this.abrirArquivo();
    }//GEN-LAST:event_jmenuAbrirActionPerformed

    private void jmenuSairActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuSairActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jmenuSairActionPerformed

    private void txtEditorKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtEditorKeyPressed
        //this.preencherPosicaoCursor();
        //this.btnCompilar.setEnabled(false);
    }//GEN-LAST:event_txtEditorKeyPressed

    private void jmenuSalvarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuSalvarActionPerformed

        this.salvarArquivo();
    }//GEN-LAST:event_jmenuSalvarActionPerformed

    private void jmenuFecharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuFecharActionPerformed

        this.fecharArquivo();
    }//GEN-LAST:event_jmenuFecharActionPerformed

    private void txtEditorKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtEditorKeyTyped
        //this.preencherPosicaoCursor();
        //this.btnCompilar.setEnabled(false);
    }//GEN-LAST:event_txtEditorKeyTyped

    private void txtEditorKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtEditorKeyReleased

        this.preencherPosicaoCursor();
        //this.btnCompilar.setEnabled(false);
    }//GEN-LAST:event_txtEditorKeyReleased

    private void txtEditorFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtEditorFocusGained

        this.preencherPosicaoCursor();

    }//GEN-LAST:event_txtEditorFocusGained

    private void txtCaminhoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtCaminhoActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtCaminhoActionPerformed

    private void btnCompilarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCompilarActionPerformed
        this.compilarCodigo();
    }//GEN-LAST:event_btnCompilarActionPerformed

    private void txtEditorMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_txtEditorMouseClicked

        this.preencherPosicaoCursor();

    }//GEN-LAST:event_txtEditorMouseClicked



    private void compilarCodigo() {

        
        Compilador comp = new Compilador( this.getNomeArquivo() );
        Mensagem mensagem = comp.compilar(this.txtEditor.getText());
        this.exibirMensagemCompilacao(mensagem);

    }
    
    /**
     * Retorna o nome do arquivo sem a sua extensão.
     * @return String nomeArquivo
     */
    private String getNomeArquivo(){
        
        //String nomeArquivo = this.arquivo.getName();
        String nomeArquivo = this.arquivo.getAbsolutePath();
        
        if( nomeArquivo.contains(".") ){
            String quebraNome[] = nomeArquivo.split("\\.");
            nomeArquivo = quebraNome[ 0 ];
        }
        
        return nomeArquivo;   
    }



    private void exibirMensagemCompilacao(Mensagem mensagem) {


        if (mensagem instanceof MensagemErro) {

            MensagemErro msgErro = (MensagemErro) mensagem;
            this.selecionarLinhaEditor(msgErro.getLinha() - 1);
        }


        this.txtErro.setText(mensagem.getMensagem());

    }



    private void selecionarLinhaEditor(int linha) {


        try {
            int offsetStart = this.txtEditor.getLineStartOffset(linha);
            int offsetEnd = this.txtEditor.getLineEndOffset(linha);

            //this.txtEditor.requestFocus();
            this.txtEditor.select(offsetStart, offsetEnd - 1);
            this.txtEditor.setSelectionColor(Color.red);
            this.txtEditor.requestFocus();


        } catch (BadLocationException ex) {

            Logger.getLogger(CompiladorView.class.getName()).log(Level.SEVERE, null, ex);
        }

    }



    private void fecharArquivo() {

        this.arquivo = null;
        this.resetTela();
    }



    private void resetTela() {

        this.txtCaminho.setText("");
        this.txtColuna.setText("");
        this.txtEditor.setText("");
        this.txtErro.setText("");
        this.txtLinha.setText("");
    }



    private void preencherPosicaoCursor() {

        int position = this.txtEditor.getCaretPosition();
        int linha = -1;
        int coluna = -1;
        try {

            linha = this.txtEditor.getLineOfOffset(position);
            coluna = position - this.txtEditor.getLineStartOffset(linha);
        } catch (BadLocationException ex) {
            Logger.getLogger(CompiladorView.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.txtLinha.setText(String.valueOf(linha + 1));
        this.txtColuna.setText(String.valueOf(coluna + 1));

    }



    private void salvarArquivo() {


        String texto = this.txtEditor.getText();
        //System.out.println(texto);

        JFileChooser jf = new JFileChooser();
        int returnVal = jf.showSaveDialog(this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

            this.arquivo = jf.getSelectedFile();
            //System.out.println(this.arquivo.toString());
            new ManipuladorDeArquivo().gravarTextoArquivo(arquivo, texto);
            this.txtCaminho.setText(this.arquivo.getAbsolutePath());
        }

        this.txtErro.setText("");
        this.btnCompilar.setEnabled(true);

    }



    private void abrirArquivo() {


        this.resetTela();

        JFileChooser jf = new JFileChooser();
        int returnVal = jf.showOpenDialog(this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {

            //this.populaVariaveis();
            this.arquivo = jf.getSelectedFile();
            this.txtCaminho.setText(this.arquivo.getAbsolutePath());
            ManipuladorDeArquivo manipulador = new ManipuladorDeArquivo(arquivo);
            String linha = manipulador.getLinha();
            while (linha != null) {

                this.inserirLinhaEditor(linha);
                linha = manipulador.getLinha();
            }
            //this.substituirRotuloPorEndereco();

            this.btnCompilar.setEnabled(true);
        }

    }



    private void inserirLinhaEditor(String linha) {

        txtEditor.append(linha + '\n');

    }



    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(CompiladorView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(CompiladorView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(CompiladorView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(CompiladorView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {


            public void run() {
                new CompiladorView().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCompilar;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JMenuItem jmenuAbrir;
    private javax.swing.JMenuItem jmenuFechar;
    private javax.swing.JMenuItem jmenuSair;
    private javax.swing.JMenuItem jmenuSalvar;
    private javax.swing.JLabel lblColuna;
    private javax.swing.JLabel lblLinha;
    private javax.swing.JPanel pnlEditor;
    private javax.swing.JTextField txtCaminho;
    private javax.swing.JTextField txtColuna;
    private javax.swing.JTextArea txtEditor;
    private javax.swing.JTextArea txtErro;
    private javax.swing.JTextField txtLinha;
    // End of variables declaration//GEN-END:variables
}
